package com.googlecode.perfectable.visuable.screen;

import static com.google.common.base.Preconditions.checkArgument;

import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

import javax.annotation.Nullable;
import javax.xml.namespace.NamespaceContext;

import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;

public class StaticNamespaceContext implements NamespaceContext {
	public static class Builder {
		private final ImmutableListMultimap.Builder<String, String> prefixesBuilder = ImmutableListMultimap.builder();

		Builder() {
		}

		public Builder bind(String namespaceURI, String prefix) {
			this.prefixesBuilder.put(namespaceURI, prefix);
			return this;
		}

		public StaticNamespaceContext build() {
			return new StaticNamespaceContext(this.prefixesBuilder.build());
		}
	}

	public static Builder builder() {
		return new Builder();
	}

	// namespaceURI -> (prefix, prefix, ...)
	private final ListMultimap<String, String> prefixes;

	StaticNamespaceContext(ListMultimap<String, String> prefixes) {
		this.prefixes = prefixes;
	}

	@Nullable
	@Override
	public String getNamespaceURI(@Nullable String prefix) {
		if(prefix == null) {
			throw new IllegalArgumentException("prefix cannot be null");
		}
		for(Entry<String, String> entry : this.prefixes.entries()) {
			if(prefix.equals(entry.getValue())) {
				return entry.getKey();
			}
		}
		return null;
	}

	@Nullable
	@Override
	public String getPrefix(@Nullable String namespaceURI) {
		checkArgument(namespaceURI != null);
		final Iterator<String> matchingPrefixes = this.getPrefixes(namespaceURI);
		if(matchingPrefixes.hasNext()) {
			return matchingPrefixes.next();
		}
		return null;
	}

	@Override
	public Iterator<String> getPrefixes(@Nullable String namespaceURI) {
		checkArgument(namespaceURI != null);
		final List<String> prefixList = this.prefixes.get(namespaceURI);
		return prefixList.iterator();
	}

}
